﻿using System;
using System.Globalization;
using System.Reflection;
using System.Text;
using UFIDA.U9.WSS.Proxy.Json;
using UFIDA.U9.WSS.Proxy.Json.Serialization;

namespace UFIDA.U9.WSS.ProxyTestService.Json
{
    /// <summary>
    ///     基础解析器
    /// </summary>
    public class BaseContractResolver : DefaultContractResolver
    {
        private readonly bool _useDataContractTransData;

        public BaseContractResolver(bool useDataContractTransData = false) : base(false)
        {
            _useDataContractTransData = useDataContractTransData;
        }

        /// <summary>
        ///     Resolves the name of the property.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        /// <returns>The property name camel cased.</returns>
        protected override string ResolvePropertyName(string propertyName)
        {
            // lower case the first letter of the passed in name
            return ToCamelCase(propertyName);
        }

        private static string ToCamelCase(string s)
        {
            if (string.IsNullOrEmpty(s))
                return s;
            if (!char.IsUpper(s[0]))
                return s;
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < s.Length; i++)
            {
                bool hasNext = i + 1 < s.Length;
                if (i == 0 || !hasNext || char.IsUpper(s[i + 1]))
                {
                    char lowerCase = char.ToLower(s[i], CultureInfo.InvariantCulture);
                    sb.Append(lowerCase);
                }
                else
                {
                    sb.Append(s.Substring(i));
                    break;
                }
            }

            return sb.ToString();
        }

        /// <summary>
        ///     Newtonsoft.Json 去掉$id IsReference = false
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public override JsonContract ResolveContract(Type type)
        {
            JsonContract contract = base.ResolveContract(type);
            contract.IsReference = false;
            return contract;
        }

        /// <summary>
        ///     创建JsonProperty
        ///     当采用DataContract时，直接返回
        ///     不采用DataContract时，只取属性并可写入的
        /// </summary>
        /// <param name="member"></param>
        /// <param name="memberSerialization"></param>
        /// <returns></returns>
        protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
        {
            JsonProperty property = base.CreateProperty(member, memberSerialization);
            if (_useDataContractTransData) return property;
            if (property == null) return null;
            if (member != null && member.MemberType == MemberTypes.Property)
            {
                PropertyInfo propertyInfo = (PropertyInfo) member;
                property.Ignored = !propertyInfo.CanWrite;
            }
            else
            {
                property.Ignored = true;
            }

            return property;
        }
    }
}